package com.palm.easy.anno.impl;

import com.palm.easy.Current;
import com.palm.easy.anno.Auth;
import com.palm.easy.domain.UserInfo;
import com.palm.easy.util.StringUtil;
import com.palm.easy.util.TokenUtil;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.wrap.MethodWrap;

import java.util.function.Function;

public class AuthHandler implements Handler {
    private static Function<String, UserInfo> userLoader;

    public static void setUserLoader(Function<String, UserInfo> loader) {
        userLoader = loader;
    }

    @Override
    public void handle(Context ctx) throws Throwable {
        if (ctx.getHandled()) {
            return;
        }
        //如果当前流程中已经处理过就跳过，避免重复处理
        if (ctx.attr("@_authed", false)) {
            return;
        }
        MethodWrap mw = ctx.action().method();
        Auth auth = mw.getAnnotation(Auth.class);
        if (auth == null) {
            auth=ctx.action().bean().annotationGet(Auth.class);
            if(auth==null){
                return;
            }
        }
        //标记已经处理过
        ctx.attrSet("@_authed", true);
        if (!auth.login()) {
            return;
        }
        UserInfo userInfo = Current.user();
        if (userInfo == null && userLoader != null) {
            String token = ctx.header("token");//.cookie("_t");
//            if(StringUtil.isEmpty(token)){
//                token=ctx.param("_token");
//            }
            String userName = TokenUtil.getData(token);
            if (userName != null) {
                UserInfo temp = userLoader.apply(userName);
                if (temp != null) {
                    if (TokenUtil.validate(token, userName, temp.getPassword())) {
                        userInfo = temp;
                        userInfo.setToken(token);
                        Current.setUser(userInfo);
                    }
                }
            }
        }
        if (userInfo == null) {
            ctx.setHandled(true);
            ctx.status(401);
            return;
        }
    }
}
